<?php
/**
 * Gère les exceptions enregistrées
 * par les autres plugins
 */

class Plugins_ErrorPlugin extends Zend_Controller_Plugin_Abstract	{
	const EXCEPTION_NO_LANGAGE = "EXCEPTION_NO_LANGAGE";
	const EXCEPTION_NO_PHOTOS = "EXCEPTION_NO_PHOTOS";
	const paramError = 'error_plugins';
	private $exceptions = array();
	
	/**
	 * Si des exceptions ont été enregitrées dans d'autres plugins
	 * alors une redirection sera faite pour une erreur
	 * 
	 * @param  Zend_Controller_Request_Abstract $request
	 * @return void
	 */
	public function preDispatch(Zend_Controller_Request_Abstract $request)
	{
		if (!$this->exceptionsIsEmpty())
		{
			// Forward to the error
			$request
			->setParam(self::paramError, $this->getErrors($request))
			->setModuleName('default')
			->setControllerName('error')
			->setActionName('error')
			->setDispatched(false);
		}
	}

	/**
	 * 
	 * @param Zend_Controller_Request_Abstract $request
	 * @return array(ArrayObject) les errors trouvées
	 */
	private function getErrors(Zend_Controller_Request_Abstract $request)
	{
		$errors = array();
		$exceptions = $this->getExceptions();
		foreach ($exceptions as $exception)
		{
			$error = $this->getError($request, $exception);
			array_push($errors, $error);
		}
		// Les exceptions ont été traitées
		$this->cleanExceptions();
		
		return $errors;
	}

	/**
	 * Retourne l'error correspondant à l'exception
	 * et à la requête donnée
	 * 
	 * @param Zend_Controller_Request_Abstract $request
	 * @return ArrayObject l'error
	 */
	private function getError(Zend_Controller_Request_Abstract $request, Exception $exception)
	{
		$error = new ArrayObject(array(), ArrayObject::ARRAY_AS_PROPS);
		$error->exception = $exception;
		if (get_class($error->exception) == 'Plugins_ExceptionLangage') {
			$error->type = self::EXCEPTION_NO_LANGAGE;
		}
		else if (get_class($error->exception) == 'Plugins_ExceptionPhotos') {
			$error->type = self::EXCEPTION_NO_PHOTOS;
		}
		else {
			$error->type = Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER;
		}
		$error->request = clone $request;

		return $error;
	}

	/**
	 * Retourne la liste d'exceptions courantes
	 *
	 * @return array(Exception) les exceptions
	 */
	public function &getExceptions()
	{
		return $this->exceptions;
	}

	/**
	 * Modifie les exceptions courantes
	 *
	 * @param array(Exception) $exceptions liste d'exceptions
	 */
	private function setExceptions(array $exceptions)
	{
		$this->exceptions = $exceptions;
	}
	
	/**
	 * Ajoute une exception
	 * 
	 * @param $exception une exception
	 */
	public function addException(Exception $exception)
	{
		array_push($this->getExceptions(), $exception);
	}
	
	/**
	 * Détermine si des exceptions ont été enregistrées
	 * 
	 * @return boolean true si des exceptions ont été levées false sinon
	 */
	public function exceptionsIsEmpty()
	{
		return count($this->getExceptions()) == 0;
	}
	
	/**
	 * Retourne la dernière exception enregistrée
	 * 
	 * @return Exception une exception
	 */
	public function lastException()
	{
		if ($this->exceptionsIsEmpty())
		{
			return end($this->getExceptions());
		}
		else
		{
			return null;
		}
	}
	
	/**
	 * Vide les exceptions
	 * 
	 * @return void
	 */
	public function cleanExceptions()
	{
		$this->setExceptions(array());
	}
}